{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python numpy教程\n",
    "\n",
    "** numpy是python中非常强大的包，它基本实现了Matlab所有常用的功能，并且有青出于蓝而胜于蓝之势。python之所以能成为数据科学领域备受欢迎的编程语言，与numpy，pandas等其它包的优化和完善是密切相关的**\n",
    "\n",
    "**这里我们将介绍一些numpy常用的功能**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### numpy的初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.  0.  0.]\n",
      " [ 0.  0.  0.]\n",
      " [ 0.  0.  0.]\n",
      " [ 0.  0.  0.]]\n"
     ]
    }
   ],
   "source": [
    "# 引入numpy包\n",
    "import numpy as np\n",
    "\n",
    "# 初始化全为0的4行3列的array\n",
    "a = np.zeros((4,3))\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.  1.  1.]\n",
      " [ 1.  1.  1.]]\n",
      "\n",
      "[[ 1.  0.  0.]\n",
      " [ 0.  1.  0.]\n",
      " [ 0.  0.  1.]]\n",
      "[[ 0.2585847   0.19647407  0.69586953  0.63570906]\n",
      " [ 0.79553497  0.72869151  0.1749098   0.98771327]\n",
      " [ 0.41650274  0.65654682  0.30400452  0.82976597]]\n",
      "\n",
      "[1 2 3 4]\n",
      "\n",
      "[[1 2 3]\n",
      " [4 5 6]]\n"
     ]
    }
   ],
   "source": [
    "# 生成全为1的array\n",
    "b = np.ones((2,3))\n",
    "print(b)\n",
    "\n",
    "print()\n",
    "# 生成单位矩阵\n",
    "eye = np.eye(3)\n",
    "print(eye)\n",
    "\n",
    "# 生成随机矩阵\n",
    "rand = np.random.random((3,4))\n",
    "print(rand)\n",
    "\n",
    "print()\n",
    "# 从list数据结构生成numpy array\n",
    "orig_list = [1,2,3,4]\n",
    "from_list = np.array(orig_list)\n",
    "print(from_list)\n",
    "print()\n",
    "\n",
    "# 从list生成2行3列数据\n",
    "orig_list = [\n",
    "    [1,2,3],\n",
    "    [4,5,6]\n",
    "]\n",
    "\n",
    "from_list = np.array(orig_list)\n",
    "print(from_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### numpy成员一些常用的函数 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['T', 'all', 'any', 'argmax', 'argmin', 'argpartition', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'ctypes', 'cumprod', 'cumsum', 'data', 'diagonal', 'dot', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'partition', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view']\n"
     ]
    }
   ],
   "source": [
    "# numpy数据类型有的一些函数\n",
    "print([x for x in dir(a) if not x.startswith('_')])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "----------\n",
      "(2, 3)\n",
      "----------\n",
      "[1 2 3 4 5 6]\n",
      "----------\n",
      "6\n",
      "1\n",
      "3.5\n",
      "21\n",
      "1.70782512766\n",
      "----------\n",
      "[[1 2]\n",
      " [3 4]\n",
      " [5 6]]\n",
      "----------\n",
      "[[1 4]\n",
      " [2 5]\n",
      " [3 6]]\n",
      "----------\n",
      "5\n",
      "----------\n",
      "[3 6]\n",
      "[1 2 3]\n"
     ]
    }
   ],
   "source": [
    "# 一些常用的函数和成员变量\n",
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "print('-'*10)\n",
    "print(a)\n",
    "print('-'*10)\n",
    "# 输出a的形状\n",
    "print(a.shape)\n",
    "print('-'*10)\n",
    "# 将a压平\n",
    "print(a.flatten())\n",
    "print('-'*10)\n",
    "# 求a的最大，最小，均值，和，方差..\n",
    "# 也可以使用np.max, np.min, np.mean, np.sum, np.std\n",
    "print(a.max())\n",
    "print(a.min())\n",
    "print(a.mean())\n",
    "print(a.sum())\n",
    "print(a.std())\n",
    "print('-'*10)\n",
    "# 将a的维度进行变形\n",
    "print(a.reshape(3,2))\n",
    "print('-'*10)\n",
    "# 将a进行转置\n",
    "print(a.T)\n",
    "print('-'*10)\n",
    "# 求a最大值的位置，同样有np.argmax\n",
    "print(a.argmax())\n",
    "print('-'*10)\n",
    "# 求a每一行的最大值， 每一列的最小值\n",
    "# 所有这些函数里面常常会有一个axis的参数，axis=0表示按对第一个维度进行计算，axis=1表示对第二个维度急性计算，axis=k表示对第k个维度\n",
    "print(a.max(axis=1))\n",
    "print(a.min(axis=0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### numpy数据的访问和修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 30 50]\n",
      " [34 15  9]]\n",
      "----------\n",
      "a的第0行第0列为10\n",
      "a的第0行第1列为30\n",
      "a的第0行第2列为50\n",
      "a的第1行第0列为34\n",
      "a的第1行第1列为15\n",
      "a的第1行第2列为9\n",
      "----------\n",
      "[30 15]\n",
      "----------\n",
      "[10 30 50]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[10,30,50],[34,15,9]])\n",
    "print(a)\n",
    "print('-'*10)\n",
    "for i, row in enumerate(a):\n",
    "    for j, col in enumerate(row):\n",
    "        v = a[i,j]\n",
    "        print(\"a的第{}行第{}列为{}\".format(i, j, v))\n",
    "print('-'*10)\n",
    "# 选取第1列\n",
    "print(a[:,1])\n",
    "print('-'*10)\n",
    "# 选取第0行\n",
    "print(a[0,:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 选取多行多列 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 30 50]\n",
      " [34 15  9]\n",
      " [ 7  8  9]]\n",
      "----------\n",
      "[[34  9]\n",
      " [ 7  9]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[10,30,50],[34,15,9],[7,8,9]])\n",
    "select_a = a[1:3, [0,2]]\n",
    "print(a)\n",
    "print('-'*10)\n",
    "print(select_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 选取满足一定条件的元素 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "[[False  True  True]\n",
      " [ True False False]\n",
      " [False False False]]\n",
      "----------\n",
      "[30 50 34]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[10,30,50],[34,15,9],[7,8,9]])\n",
    "select_index = (a > 15)\n",
    "print('-'*10)\n",
    "print(select_index)\n",
    "print('-'*10)\n",
    "print(a[select_index])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 修改元素 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 30 50]\n",
      " [34 15  9]]\n",
      "----------\n",
      "[[ 10  30  50]\n",
      " [ 34  15 100]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[10,30,50],[34,15,9]])\n",
    "print(a)\n",
    "print('-'*10)\n",
    "a[1,2] = 100\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "** 设置数据格式 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "int32\n",
      "float64\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3], dtype=np.int)\n",
    "b = np.array([1,2,3], dtype=np.float)\n",
    "\n",
    "print(a.dtype)\n",
    "print(b.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### numpy array的运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  6.   8.]\n",
      " [ 10.  12.]]\n",
      "[[  6.   8.]\n",
      " [ 10.  12.]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([[1,2],[3,4]], dtype=np.float64)\n",
    "y = np.array([[5,6],[7,8]], dtype=np.float64)\n",
    "\n",
    "# 元素对元素的加法\n",
    "print(x + y)\n",
    "print(np.add(x, y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-4. -4.]\n",
      " [-4. -4.]]\n",
      "[[-4. -4.]\n",
      " [-4. -4.]]\n"
     ]
    }
   ],
   "source": [
    "# 元素对元素的减法\n",
    "print(x - y)\n",
    "print(np.subtract(x, y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  5.  12.]\n",
      " [ 21.  32.]]\n",
      "[[  5.  12.]\n",
      " [ 21.  32.]]\n"
     ]
    }
   ],
   "source": [
    "# 元素对元素的乘法\n",
    "print(x * y)\n",
    "print(np.multiply(x, y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.2         0.33333333]\n",
      " [ 0.42857143  0.5       ]]\n",
      "[[ 0.2         0.33333333]\n",
      " [ 0.42857143  0.5       ]]\n"
     ]
    }
   ],
   "source": [
    "# 元素对元素的除法\n",
    "print(x / y)\n",
    "print(np.divide(x, y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.          1.41421356]\n",
      " [ 1.73205081  2.        ]]\n"
     ]
    }
   ],
   "source": [
    "# 每个元素求平方根\n",
    "print(np.sqrt(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11\n",
      "11\n"
     ]
    }
   ],
   "source": [
    "# 计算两个向量的内积\n",
    "a = np.array([1,2])\n",
    "b = np.array([3,4])\n",
    "\n",
    "print(a.dot(b))\n",
    "print(np.dot(a, b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 19.  22.]\n",
      " [ 43.  50.]]\n",
      "[[ 19.  22.]\n",
      " [ 43.  50.]]\n"
     ]
    }
   ],
   "source": [
    "# 计算两个矩阵的乘积\n",
    "print(x.dot(y))\n",
    "print(np.dot(x, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Broadcasting\n",
    "\n",
    "** 如果两个运算的numpy array维度不一样，numpy会尝试自动进行Broadcasting，然后再进行运算。对于任意的两个维度的数组，在每一个维度上都会使最大的数固定，然后判定最小的数是否能进行扩充。比如一个矩阵是2x3，另外一个矩阵是1x3，numpy会判断每一个维度上最大的数值，第一个维度上分别是2和1，最大的是2，而1能二倍扩充到2，所以第一个维度可以；对于第二维度，分别为3和3，数字是一样的，不需要进行扩充，则可以直接进行运算 **\n",
    "\n",
    "** 对于任意维度的两个矩阵，比如说，AxBxC，DxE，broadcasting的运算规则如下**\n",
    "* 首先保证两个维度个数一样，不一样的话在少的前面补1，所以上面的维度变成了AxBxC和1xDxE\n",
    "* 依次比较每个维度上的最大数是否为最小数的倍数，如果是的话对小的数进行对应维度上的直接扩充累加，如果不是的话就报错中断\n",
    "\n",
    "** Broadcasting是很强大和实用的功能，需要时间和经验的积累去理解和体会 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "----------\n",
      "[1 1 1]\n",
      "----------\n",
      "[[2 3 4]\n",
      " [5 6 7]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([\n",
    "    [1, 2, 3],\n",
    "    [4, 5, 6]\n",
    "], dtype=np.int32)\n",
    "\n",
    "b = np.array([1,1,1])\n",
    "print('-'*10)\n",
    "print(a)\n",
    "print('-'*10)\n",
    "print(b)\n",
    "print('-'*10)\n",
    "print(a+b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 1 1]\n",
      " [1 1 1]]\n",
      "----------\n",
      "[[2 3 4]\n",
      " [5 6 7]]\n"
     ]
    }
   ],
   "source": [
    "#而上面的运算等价于首先讲b堆积两行，然后进行相加\n",
    "tmp_b = np.tile(b, (2,1))\n",
    "print(tmp_b)\n",
    "print('-'*10)\n",
    "print(a+tmp_b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### numpy的其它一些常用的功能\n",
    "\n",
    "** 生成序列，和range一样，只不过直接生成numpy的array **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 3, 5, 7, 9])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.arange(1, 10, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 两个相同维度数组的横向或纵向合并 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]\n",
      " [5 6]\n",
      " [7 8]]\n",
      "----------\n",
      "[[1 2 5 6]\n",
      " [3 4 7 8]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2],[3,4]])\n",
    "b = np.array([[5,6],[7,8]])\n",
    "\n",
    "print(np.vstack([a,b]))\n",
    "print('-'*10)\n",
    "print(np.hstack([a,b]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "** numpy中的NaN **\n",
    "\n",
    "** NaN(Not a Number)表示数据并非是数字的空值 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "nan"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.NaN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.NaN == np.NaN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.NaN is np.NaN"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
